#include "reg52.h"
#include <AT89x51.h>
#include <intrins.h>
sbit IN1 = P1 ^ 0; //??
sbit IN2 = P1 ^ 1;
sbit IN3 = P1 ^ 2;
sbit IN4 = P1 ^ 3;

sbit k1 = P1 ^ 4; //????
sbit k2 = P1 ^ 5;
sbit k3 = P1 ^ 6;
sbit k4 = P1 ^ 7;

sbit left_dodge = P3 ^ 4;  //
sbit right_dodge = P3 ^ 5; //
sbit left_find = P3 ^ 6;   //???
sbit right_find = P3 ^ 7;  //???

sbit RX = P2 ^ 0; //
sbit TX = P2 ^ 1;

#define Imax 14000
#define Imin 8000
#define Inum1 1450
#define Inum2 700
#define Inum3 3000

unsigned char f = 0;
unsigned char Im[4] = {0x00, 0x00, 0x00, 0x00};
unsigned char show[2] = {0, 0};
unsigned long m, Tc;
unsigned char IrOK;

void alone();
void dodge();
void search();
void red();
void outvolice();

unsigned char pwm_left_val = 150;
unsigned char pwm_right_val = 150;
unsigned char pwm_t;
unsigned int time = 0;
unsigned long S = 0;
bit flag = 0;

void delay_ms(unsigned int nms)
{
	unsigned int i, j;
	for (i = nms; i > 0; i--)
		for (j = 113; j > 0; j--)
			;
}

void stop()
{

	IN1 = 0;
	IN2 = 0;
	IN3 = 0;
	IN4 = 0;
}

void run()
{
	IN1 = 1;
	IN2 = 0;
	IN3 = 1;
	IN4 = 0;
}

void back_run()
{
	IN1 = 0;
	IN2 = 1;
	IN3 = 0;
	IN4 = 1;
}

void left_run()
{
	IN1 = 0;
	IN2 = 0;
	IN3 = 1;
	IN4 = 0;
}

void left_turn()
{
	IN1 = 0;
	IN2 = 1;
	IN3 = 1;
	IN4 = 0;
}

void right_run()
{
	IN1 = 1;
	IN2 = 0;
	IN3 = 0;
	IN4 = 0;
}

void right_turn()
{
	IN1 = 1;
	IN2 = 0;
	IN3 = 0;
	IN4 = 1;
}

void alone()
{
	if (k1 == 0)
	{
		delay_ms(100);
		if (k1 == 0)
		{
			IN1 = 1;
			IN2 = 0;
			IN3 = 1;
			IN4 = 0;
		}
	}
	if (k2 == 0)
	{
		delay_ms(100);
		if (k2 == 0)
		{
			left_run();
		}
	}
	if (k3 == 0)
	{
		delay_ms(100);
		if (k3 == 0)
		{
			right_run();
		}
	}
	if (k4 == 0)
	{
		delay_ms(100);
		if (k4 == 0)
		{
			back_run();
		}
	}
}

void key()
{
	if (k1 == 0 && k2 == 0)
	{
		delay_ms(100);
		if (k1 == 0 && k2 == 0)
		{
			while (1)
			{
				alone();
			}
		}
	}
	if (k1 == 0 && k3 == 0)
	{
		delay_ms(100);
		if (k1 == 0 && k3 == 0)
		{
			while (1)
			{
				dodge();
			}
		}
	}
	if (k1 == 0 && k4 == 0)
	{
		delay_ms(100);
		if (k1 == 0 && k4 == 0)
		{
			while (1)
			{
				search();
			}
		}
	}
	if (k2 == 0 && k3 == 0)
	{
		delay_ms(100);
		if (k2 == 0 && k3 == 0)
		{
			while (1)
			{
				red();
			}
		}
	}
	if (k2 == 0 && k4 == 0)
	{
		delay_ms(100);
		if (k2 == 0 && k4 == 0)
		{
			while (1)
			{
				outvolice();
			}
		}
	}
}

void dodge()
{
	if (left_dodge == 1 && right_dodge == 1)
	{
		run();
	}
	if (left_dodge == 0 && right_dodge == 1)
	{
		right_turn();
		delay_ms(200);
	}
	if (left_dodge == 1 && right_dodge == 0)
	{
		left_turn();
		delay_ms(200);
	}
	if (left_dodge == 0 && right_dodge == 0)
	{
		back_run();
		delay_ms(200);
	}
}

void search()
{
	if (left_find == 0 && right_find == 0)
	{
		run();
	}
	if (left_find == 1 && right_find == 0)
	{
		right_run();
		delay_ms(10);
	}
	if (left_find == 0 && right_find == 1)
	{
		left_run();
		delay_ms(10);
	}
	if (left_find == 1 && right_find == 1)
	{
		run();
		delay_ms(10);
	}
}

void delay(unsigned int k)
{
	unsigned int x, y;
	for (x = 0; x < k; x++)
		for (y = 0; y < 2000; y++)
			;
}

void intersvr1(void) interrupt 2 using 1
{
	Tc = TH0 * 256 + TL0;
	TH0 = 0;
	TL0 = 0;
	if ((Tc > Imin) && (Tc < Imax))
	{
		m = 0;
		f = 1;
		return;
	}

	if (f == 1)
	{
		if (Tc > Inum1 && Tc < Inum3)
		{
			Im[m / 8] = Im[m / 8] >> 1 | 0x80;
			m++;
		}
		if (Tc > Inum2 && Tc < Inum1)
		{
			Im[m / 8] = Im[m / 8] >> 1;
			m++;
		}
		if (m == 32)
		{
			m = 0;
			f = 0;
			if (Im[2] == ~Im[3])
			{
				IrOK = 1;
			}
			else
				IrOK = 0;
		}
	}
}

void red()
{

	m = 0;
	f = 0;

	IT1 = 1;
	EX1 = 1;

	TMOD = 0x11;
	TH0 = 0;
	TL0 = 0;
	TR0 = 1;
	EA = 1;

	delay(100);

	while (1)
	{

		if (IrOK == 1)
		{
			switch (Im[2])
			{
			case 0x46:
				run();
				break;
			case 0x15:
				back_run();
				break;
			case 0x44:
				left_turn();
				break;
			case 0x43:
				right_turn();
				break;
			case 0x40:
				stop();
				break;
			default:
				break;
			}

			IrOK = 0;
		}
	}
}

void Delay10us(unsigned char i)
{
	unsigned char j;
	do
	{
		j = 10;
		do
		{
			_nop_();
		} while (--j);
	} while (--i);
}

void Conut()
{
	time = TH0 * 256 + TL0;
	TH0 = 0;
	TL0 = 0;

	S = (float)(time * 1.085) * 0.17;
	if ((S >= 7000) || flag == 1)
	{
		flag = 0;
	}
}

void Avoid()
{
	if (S > 150)
	{
		run();
	}
	else
	{
		back_run();
	}
}

void StartModule()
{
	TX = 1;
	Delay10us(2);
	TX = 0;
}

void outvolice()
{
	TMOD |= 0x20;
	TMOD |= 0x01;
	TH1 = 220;
	TL1 = 220;
	TH0 = 0;
	TL0 = 0;
	ET1 = 1;
	ET0 = 1;
	TR1 = 1;
	EA = 1;
	while (1)
	{
		StartModule();
		while (!RX)
			;
		TR0 = 1;
		while (RX)
			;
		TR0 = 0;
		Conut();
		Avoid();
	}
}

void main()
{
	stop();
	key();
}